package com.tmc.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPOutputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClientUtil {

	/**
	 * 字符编码
	 */
	public final static String charset = "UTF-8";
	
	/**
	 * 是否代理
	 */
	public final static boolean isProxy = false;
	
	/**
	 * 代理服务器
	 */
	public final static String proxyHost = "192.168.4.200";

	/**
	 * 代理服端口
	 */
	public final static int proxyPort = 808;
	
	/**
     * 请求超时
     */
    public static final int CONNECT_TIMEOUT=60000;
    
    /**
     * 读取超时
     */
    public static final int REQUEST_TIMEOUT=60000;
    
    /**
     * 默认请求配置
     */
	private static RequestConfig requestConfig = RequestConfig.custom()
			.setSocketTimeout(CONNECT_TIMEOUT)
			.setConnectTimeout(CONNECT_TIMEOUT)
			.setConnectionRequestTimeout(REQUEST_TIMEOUT).build();
	
	/**
     * 默认请求配置
     */
	@SuppressWarnings("unused")
	private static RequestConfig getRequestConfig(int connectTimeout,int readTimeout){
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setSocketTimeout(connectTimeout)
                .setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(readTimeout)
                .build();
        return defaultRequestConfig;
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 *            地址
	 */
	public static String sendHttpPost(String httpUrl, String username, String password) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		HttpClientContext context = getHttpClientContext(httpUrl, username, password);
		return sendHttpPost(httpPost, context);
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 *            地址
	 * @param params
	 *            参数(格式:key1=value1&key2=value2)
	 */
	public static String sendHttpPost(String httpUrl, String params, String username, String password) throws Exception {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		// context
		HttpClientContext context = getHttpClientContext(httpUrl, username, password);
		// 设置参数
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPOutputStream gzip = new GZIPOutputStream(out);
		if (params != null && !"".equals(params)) {
			gzip.write(params.getBytes());
		}
		gzip.close();
		ByteArrayEntity requestEntity = new ByteArrayEntity(out.toByteArray());
		httpPost.setEntity(requestEntity);
		//httpPost.setEntity(new StringEntity(params));
		httpPost.addHeader("Content-Type", "text/html;charset=UTF-8");
		httpPost.addHeader("accept-encoding", "gzip");
		httpPost.addHeader("content-encoding", "gzip");
		return sendHttpPost(httpPost, context);
	}
	
	public static String sendHttpGet(String httpUrl, String encode) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpGet(httpGet, encode);
	}
	
	public static String sendHttpGet(HttpGet httpGet, String encode) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, encode);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 *            地址
	 * @param maps
	 *            参数
	 */
	public static String sendHttpPost(String httpUrl, Map<String, String> maps) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		if (maps != null){
			for (String key : maps.keySet()) {
				nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
			}
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	public static String sendHttpPost(CloseableHttpClient client, String httpUrl, Map<String, String> maps) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		if (maps != null){
			for (String key : maps.keySet()) {
				nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
			}
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(client, httpPost);
	}
	
	public static String sendSoapHttpPost(String httpUrl, String xml) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列
		try {
			httpPost.setEntity(new StringEntity(xml, "UTF-8"));
			httpPost.setHeader("Content-Type", "text/xml; charset=UTF-8");  
	        httpPost.setHeader("SOAPAction", "http://tempuri.org/ProcessRequest"); 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	public static String sendSoapHttpPost(String httpUrl, String xml, String soapAction) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列
		try {
			httpPost.setEntity(new StringEntity(xml, "UTF-8"));
			httpPost.setHeader("Content-Type", "text/xml; charset=UTF-8");  
	        httpPost.setHeader("SOAPAction", soapAction); 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	public static String sendJsonHttpPost(String httpUrl,String jsonStr){
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		try {
			httpPost.setEntity(new StringEntity(jsonStr, "UTF-8"));
			httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
			httpPost.addHeader("content-Type", "text/xml");
		} catch (Exception e) {
		}
		return sendHttpPost(httpPost);
	}
	
	
	public static String sendHttpPostWithCookie(String httpUrl, Map<String, String> maps, CookieStore cookie) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		if (maps != null){
			for (String key : maps.keySet()) {
				nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
			}
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPostWithCookie(httpPost, cookie);
	}
	
	public static String sendHttpPostSetCookie(String httpUrl, Map<String, String> maps, CookieStore cookie) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost // 创建参数队列
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		if (maps != null){
			for (String key : maps.keySet()) {
				nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
			}
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPostSetCookie(httpPost, cookie);
	}

	/**
	 * 发送 post请求（带文件）
	 * 
	 * @param httpUrl
	 *            地址
	 * @param maps
	 *            参数
	 * @param fileLists
	 *            附件
	 *//*
		 * public String sendHttpPost(String httpUrl, Map<String, String> maps,
		 * List<File> fileLists) { HttpPost httpPost = new HttpPost(httpUrl);//
		 * 创建httpPost MultipartEntityBuilder meBuilder =
		 * MultipartEntityBuilder.create(); for (String key : maps.keySet()) {
		 * meBuilder.addPart(key, new StringBody(maps.get(key),
		 * ContentType.TEXT_PLAIN)); } for (File file : fileLists) { FileBody
		 * fileBody = new FileBody(file); meBuilder.addPart("files", fileBody);
		 * } HttpEntity reqEntity = meBuilder.build();
		 * httpPost.setEntity(reqEntity); return sendHttpPost(httpPost); }
		 */

	/**
	 * 发送Post请求
	 * 
	 * @param httpPost
	 * @return
	 */
	private static String sendHttpPost(HttpPost httpPost, HttpClientContext context) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			if (isProxy){
				httpClient = HttpClients.custom().setRoutePlanner(getProxyRoutePlanner()).build();
			} else {
				httpClient = HttpClients.custom().build();
			}
			httpPost.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(context.getTargetHost(), httpPost, context);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	public static void setCookieStore(HttpResponse httpResponse, CookieStore cookieStore) {
	    // JSESSIONID
	    String setCookie = httpResponse.getFirstHeader("Set-Cookie").getValue();
	    String JSESSIONID = setCookie.substring("JSESSIONID=".length(), setCookie.indexOf(";"));
	    // 新建一个Cookie
	    BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", JSESSIONID);
	    cookie.setVersion(0);
	    cookie.setDomain("192.168.2.9");
	    cookie.setPath("/");
	    cookieStore.addCookie(cookie);
	  }
	
	public static String sendHttpPost(CloseableHttpClient httpClient, HttpPost httpPost) {
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		boolean isClose = false;
		try {
			// 创建默认的httpClient实例.
			if (httpClient == null){
				httpClient = HttpClients.createDefault();
				httpPost.setConfig(requestConfig);
				isClose = true;
			}
			//httpPost.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null && isClose) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	public static String sendHttpPost(HttpPost httpPost) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			if (isProxy){
				httpClient = HttpClients.custom().setRoutePlanner(getProxyRoutePlanner()).build();
			} else {
				httpClient = HttpClients.custom().build();
			}
 			httpPost.setConfig(requestConfig);     
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	public static String sendHttpPostWithCookie(HttpPost httpPost, CookieStore cookieStore) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
			httpPost.setConfig(requestConfig);;
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	public static String sendHttpPostSetCookie(HttpPost httpPost, CookieStore cookie) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.custom().setDefaultCookieStore(cookie).build();
			httpPost.setConfig(requestConfig);;
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
			// cookie
			setCookieStore(response, cookie);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	public static HttpClientContext context = null;

	private static HttpClientContext getHttpClientContext(String url, String username, String password) {
		//if (context == null) {
			context = HttpClientContext.create();
			HttpHost targetHost = new HttpHost("ibeplus.tehang.com", 12344, "http");
			UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
			CredentialsProvider credsProvider = new BasicCredentialsProvider();
			credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()), creds);
			// Create AuthCache instance
			AuthCache authCache = new BasicAuthCache();
			// Generate BASIC scheme object and add it to the local auth cache
			BasicScheme basicAuth = new BasicScheme();
			authCache.put(targetHost, basicAuth);
			// Add AuthCache to the execution context
			context.setCredentialsProvider(credsProvider);
			context.setAuthCache(authCache);
			context.setTargetHost(targetHost);
		//}
		return context;
	}
	
	public static HttpHost proxy = null;
	

	public static DefaultProxyRoutePlanner routePlanner = null;

	private static DefaultProxyRoutePlanner getProxyRoutePlanner() {
		if (routePlanner == null) {
			if (proxy == null) {
				proxy = new HttpHost(proxyHost, proxyPort, "http");
			}
			routePlanner = new DefaultProxyRoutePlanner(proxy);
		}
		return routePlanner;
	}

	/**
	 * 发送 get请求
	 * 
	 * @param httpUrl
	 */
	public static String sendHttpGet(String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpGet(httpGet);
	}
	
	public static String sendHttpGet(CloseableHttpClient client, String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpGet(client, httpGet);
	}
	
	public static String sendHttpGetWithCookie(String httpUrl, CookieStore cookieStore) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpGetWithCookie(httpGet, cookieStore);
	}

	/**
	 * 发送 get请求Https
	 * 
	 * @param httpUrl
	 */
	public static String sendHttpsGet(String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpsGet(httpGet);
	}

	/**
	 * 发送Get请求
	 * 
	 * @param httpPost
	 * @return
	 */
	private static String sendHttpGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	private static String sendHttpGet(CloseableHttpClient httpClient, HttpGet httpGet) {
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		boolean isClose = false;
		try {
			// 创建默认的httpClient实例.
			if (httpClient == null){
				httpClient = HttpClients.createDefault();
				httpGet.setConfig(requestConfig);
				isClose = true;
			}
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null && isClose) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	public static String sendHttpGetWithCookie(HttpGet httpGet, CookieStore cookieStore) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
			httpGet.setConfig(requestConfig);;
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	/**
	 * 发送Get请求Https
	 * 
	 * @param httpPost
	 * @return
	 */
	private static String sendHttpsGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader
					.load(new URL(httpGet.getURI().toString()));
			DefaultHostnameVerifier hostnameVerifier = new

			DefaultHostnameVerifier(publicSuffixMatcher);
			httpClient = HttpClients.custom().setSSLHostnameVerifier

			(hostnameVerifier).build();
			httpGet.setConfig(requestConfig);
			
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	
	/**
	 * 翻墙代理
	 * 
	 */
	public static HttpHost googleMapsProxy = null;
	public static String googleMapsProxyHost = "127.0.0.1";
	public static int googleMapsProxyPort = 38251;
	public static DefaultProxyRoutePlanner googleMapsRoutePlanner = null;

	private static DefaultProxyRoutePlanner getProxyGoogleMapsRoutePlanner() {
		if (googleMapsRoutePlanner == null) {
			if (googleMapsProxy == null) {
				googleMapsProxy = new HttpHost(googleMapsProxyHost, googleMapsProxyPort, "http");
			}
			googleMapsRoutePlanner = new DefaultProxyRoutePlanner(googleMapsProxy);
		}
		return googleMapsRoutePlanner;
	}
	
	/**
	 * 谷歌翻墙代理
	 * 
	 */
	public static String sendHttpGetToGoogle(String httpUrl){
		HttpGet httpGet = new HttpGet(httpUrl);
		return sendHttpGetToGoogle(httpGet);
	}
	
	/**
	 * 发送Get请求Https
	 * 翻墙代理地址: 127.0.0.1:38251
	 * @param httpPost
	 * @return
	 */
	
	private static String sendHttpGetToGoogle(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			if (isProxy){
				httpClient = HttpClients.custom().setRoutePlanner(getProxyGoogleMapsRoutePlanner()).build();
			} else {
				httpClient = HttpClients.custom().build();
			}
			httpGet.setConfig(requestConfig);
			
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
}